package gd.qaq.blue.bluespick.listener;

import com.gmail.filoghost.holographicdisplays.api.Hologram;
import gd.qaq.blue.bluespick.BluesPick;
import gd.qaq.blue.bluespick.api.PickAPI;
import gd.qaq.blue.bluespick.dto.AreaData;
import gd.qaq.blue.bluespick.dto.PickBlockData;
import gd.qaq.blue.bluespick.entity.PickHologram;
import gd.qaq.blue.bluespick.entity.PickingTask;
import gd.qaq.blue.bluespick.util.BlockUtil;
import gd.qaq.blue.bluespick.util.area.Area;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static gd.qaq.blue.bluespick.util.ItemUtil.checkItemHasMeta;
import static gd.qaq.blue.bluespick.util.ItemUtil.createItem;
import static gd.qaq.blue.bluespick.util.StringUtil.*;

public class AreaListener implements Listener {
    public static Map<String, Location[]> choosingPlayers = new HashMap<>();

    @EventHandler
    public void onPlayerPlaceBlock(BlockPlaceEvent event){
        if(PickAPI.checkInArea(event.getBlock())!=null || PickAPI.checkInArea(event.getPlayer())!=null){
            event.setCancelled(true);
            if(PickAPI.isPickBlock(event.getBlock())==null)
                error(event.getPlayer(),"这里是采集区域,你没有权限放置物品");
        }
    }

    @EventHandler
    public void onPlayerMove(PlayerMoveEvent event){
        Player player = event.getPlayer();
        PickingTask pickingTask = BluesPick.pickingPlayers.get(player.getName());
        //判断用户是否在采集中移动了
        if(pickingTask!=null){
            //如果移动了，则取消采集
            if(event.getFrom().distance(event.getTo())>=0.1){
                Location location = new Location(Bukkit.getWorld(pickingTask.getData().getWorld()),
                        pickingTask.getData().getX(), pickingTask.getData().getY(), pickingTask.getData().getZ());
                BluesPick.pickingPlayers.remove(player.getName());
                BluesPick.pickingBlock.remove(location.getWorld().getName() + "&&" +
                        location.getX() + "&&" + location.getY() + "&&" + location.getZ());
                PickHologram pickHologram = BluesPick.holograms.get(
                        location.getWorld().getName() + "&&" +
                                location.getX() + "&&" + location.getY() + "&&" + location.getZ()
                );
                //重置全息图
                pickHologram.getHologram().clearLines();
                pickHologram.getHologram().appendTextLine(colorFormat(pickingTask.getData().getPickName().replace(";;", " ") + " &7&l||||||||||"));
                pickingTask.getTask().cancel();
                error(player,"因为采集过程中移动了，采集已被取消");
            }
        }
    }
    @EventHandler
    public void onPlayerDestroy(BlockBreakEvent event){
        if(PickAPI.checkInArea(event.getBlock())!=null || PickAPI.checkInArea(event.getPlayer())!=null){
            event.setCancelled(true);
            if(PickAPI.isPickBlock(event.getBlock())==null)
                error(event.getPlayer(),"这里是采集区域,你没有权限破坏");
        }
    }


    @EventHandler
    public void onPlayerEditInv(InventoryCloseEvent event){
        Inventory inv = event.getInventory();
        String invName = inv.getName();
        ItemStack[] content = inv.getContents();
        List<gd.qaq.blue.bluespick.entity.ItemStack> contents = new ArrayList<>();
        int count = 1;
        for (ItemStack stack : content) {
            if(stack!=null){
                BluesPick.plugin.getLogger().info("第"+count+"位置有数据");
                gd.qaq.blue.bluespick.entity.ItemStack itemStack = new gd.qaq.blue.bluespick.entity.ItemStack();
                itemStack.setItem(stack);
                itemStack.setPosition(count - 1);
                contents.add(itemStack);
            }
            count++;
        }
        String uuid = event.getPlayer().getUniqueId().toString();
        Location[] locations = AreaListener.choosingPlayers.get(uuid);
        BluesPick.plugin.getLogger().info("已关闭"+invName);
        if(locations==null) return;
        if(invName.equalsIgnoreCase("§b§l采集工具管理菜单")){
            boolean b = BluesPick.jdbcUtils.setItems(true, PickAPI.isPickBlock(locations[2].getBlock()), contents.toArray(new gd.qaq.blue.bluespick.entity.ItemStack[]{}));
            if(b)success(event.getPlayer(),"采集工具已保存");
            else error(event.getPlayer(),"采集工具保存失败");
        }else if(invName.equalsIgnoreCase("§e§l掉落物管理菜单")){
            boolean b =  BluesPick.jdbcUtils.setItems(false,PickAPI.isPickBlock(locations[2].getBlock()),contents.toArray(new gd.qaq.blue.bluespick.entity.ItemStack[]{}));
            if(b)success(event.getPlayer(),"掉落物已保存");
            else error(event.getPlayer(),"掉落物保存失败");
        }
    }

    @EventHandler
    public void onPlayerSwing(PlayerInteractEvent event) {
        Player player = event.getPlayer();
        ItemStack item = player.getItemInHand();
        String action = checkHand(event, item);
        if(action!=null) {
            String uuid = player.getUniqueId().toString();
            Block clickedBlock = event.getClickedBlock();  BluesPick.plugin.getLogger().info("block点击位置: "+clickedBlock.getLocation().serialize()+"&&"+clickedBlock.getLocation().getPitch()+"&&"+clickedBlock.getLocation().getYaw()+"&&"+clickedBlock.getChunk().getX()+"&&"+clickedBlock.getChunk().getZ()+"&&"+clickedBlock.getWorld().getName()+"&&"+
                    clickedBlock.getX()+"&&"+clickedBlock.getY()+"&&"+clickedBlock.getZ());
            if (BlockUtil.checkBlockIsEmpty(clickedBlock)) {
                return;
            }
            Location location = clickedBlock.getLocation();
            event.setCancelled(true);
            Location locations[] = null;
            if (!choosingPlayers.containsKey(uuid)) {
                locations = new Location[3];
                choosingPlayers.put(uuid, locations);
            } else {
                locations = choosingPlayers.get(uuid);
            }
            if(action.equalsIgnoreCase("picking")){
                PickingTask pickingTask1 = BluesPick.pickingPlayers.get(player.getName());
                if(pickingTask1!=null){
                    success(player,"你正在采集&f"+pickingTask1.getData().getPickName()+"&a中...");
                    return;
                }
                //如果用户在采集中，则根据方块拿到全息图方便修改
                PickBlockData pickBlock = PickAPI.isPickBlock(clickedBlock);
                //先判断下方块是否被别人采集了
                Player pickingPlayer = BluesPick.pickingBlock.get(location.getWorld().getName() + "&&" +
                        location.getX() + "&&" + location.getY() + "&&" + location.getZ());
                if(pickingPlayer!=null){
                    //告知用户此处已经有人采集了
                    error(player,("这个&f"+pickBlock.getPickName()+"&c正在被采集中").replace(";;",""));
                    return;
                }
                PickHologram pickHologram = BluesPick.holograms.get(
                        location.getWorld().getName() + "&&" +
                                location.getX() + "&&" + location.getY() + "&&" + location.getZ()
                );
                BluesPick.plugin.getLogger().info("采集：点击位置: "+location.getWorld().getName()+"&&"+
                        location.getX()+"&&"+location.getY()+"&&"+location.getZ());
                BluesPick.plugin.getLogger().info("block点击位置: "+clickedBlock.getLocation().serialize()+"&&"+clickedBlock.getLocation().getPitch()+"&&"+clickedBlock.getLocation().getYaw()+"&&"+clickedBlock.getChunk().getX()+"&&"+clickedBlock.getChunk().getZ()+"&&"+clickedBlock.getWorld().getName()+"&&"+
                        clickedBlock.getX()+"&&"+clickedBlock.getY()+"&&"+clickedBlock.getZ());
                if(pickHologram==null)return;
                //根据时间修改采集物全息图
                Hologram hologram = pickHologram.getHologram();
                PickingTask pickingTask = new PickingTask();
                //新建一个采集任务，添加到采集队列中
                BukkitTask task = new BukkitRunnable() {
                    @Override
                    public void run() {
                        //获取对应任务
                        PickingTask task = BluesPick.pickingPlayers.get(player.getName());
                        if(task==null) return;
                        Location location1 = new Location(Bukkit.getWorld(task.getData().getWorld()), task.getData().getX(), task.getData().getY(), task.getData().getZ());
                        Double pickTime = task.getData().getPickTime();
                        Long everyTime = Long.parseLong((""+((pickTime/11) * 1000)).split("\\.")[0]);
                        //每十分之一的时间执行一次
                        if(!(System.currentTimeMillis() - task.getStartTime() >= everyTime))return;
                        task.setStartTime(System.currentTimeMillis());
                        //先判断下方块是否已经记录采集了
                        Player pickingPlayer = BluesPick.pickingBlock.get(location1.getWorld().getName() + "&&" +
                                location1.getX() + "&&" + location1.getY() + "&&" + location1.getZ());
                        //如果没记录
                        if(pickingPlayer==null) {
                            //将方块标记到采集队列中
                            BluesPick.pickingBlock.put(location1.getWorld().getName() + "&&" +
                                    location1.getX() + "&&" + location1.getY() + "&&" + location1.getZ(), player);
                        }
                        //如果任务已经拿到，开始修改全息图
                        String process = "";
                        for(int i = task.getProcess();i>0;i--){
                            process+="&7&l|";
                        }
                        while(process.replaceAll("&\\S{1}","").length()<10){
                            process+="&a&l|";
                        }
                        hologram.clearLines();
                        hologram.appendTextLine(
                                colorFormat(pickBlock.getPickName().replace(";;"," ")+" "+process)
                        );
                        int res = task.getProcess()-1;
                        //如果进度为0，说明采集结束了，则取消任务
                        if(res<0){
                            //随机掉落物品采集物
                            List<gd.qaq.blue.bluespick.entity.ItemStack> drops = task.getData().getDrops();
                            if(drops.size()<=0){
                                error(player,"这个采集物什么东西也没有");
                            }else {
                                gd.qaq.blue.bluespick.entity.ItemStack itemStack = drops.get((int) (Math.random() * drops.size()));
                                //在方块位置掉落物品
                                player.getWorld().dropItem(location1, itemStack.getItem());
                                String displayName = "未知物";
                                ItemMeta itemMeta = itemStack.getItem().getItemMeta();
                                if (itemMeta != null) {
                                    String displayName1 = itemMeta.getDisplayName();
                                    String localizedName = itemMeta.getLocalizedName();
                                    displayName = displayName1 != null ? displayName1 : localizedName != null ? localizedName : "未知物";
                                }
                                //发送消息
                                success(player, "你采集到了&f" + displayName + "*&e" + itemStack.getItem().getAmount());
                            }
                                //取消任务并删除队列中的任务
                                BluesPick.pickingPlayers.remove(player.getName());
                                BluesPick.pickingBlock.remove(location1.getWorld().getName() + "&&" +
                                        location1.getX() + "&&" + location1.getY() + "&&" + location1.getZ());
                                //重置全息图
                                hologram.clearLines();
                                hologram.appendTextLine(colorFormat(pickBlock.getPickName().replace(";;", " ") + " &7&l||||||||||"));
                                cancel();

                        }else{
                            task.setProcess(res);
                        }
                    }
                }.runTaskTimer(BluesPick.plugin, 0, 2L);
                pickingTask.setTask(task);
                pickingTask.setData(pickBlock);
                pickingTask.setStartTime(System.currentTimeMillis());
                BluesPick.pickingPlayers.put(player.getName(),pickingTask);
            }else if (action.equalsIgnoreCase("left") || action.equalsIgnoreCase("right")) {
                switch (action) {
                    case "left":
                        locations[0] = location;
                        success(player, "&e你选择了第一个点: X:" + location.getX() + ",Y:" + location.getY() + ",Z:" + location.getZ());
                        break;
                    case "right":
                        locations[1] = location;
                        success(player, "&e你选择了第二个点: X:" + location.getX() + ",Y:" + location.getY() + ",Z:" + location.getZ());
                        break;
                }
                choosingPlayers.put(uuid, locations);
            } else if (action.equalsIgnoreCase("setPick")) {
                event.setCancelled(true);
                //1. 判断方块是否存在采集区域中
                AreaData areaData = PickAPI.checkInArea(clickedBlock);
                if(areaData==null){
                    error(player,"你需要先身处一个采集区域中才能进行该操作");
                    return;
                }
                //2. 判断方块是否为采集物
                PickBlockData pickBlock = PickAPI.isPickBlock(clickedBlock);
                locations[2] = clickedBlock.getLocation();
                choosingPlayers.put(uuid, locations);
                if(pickBlock==null){
                    //如果不是采集物,提示
                    success(player, "&e你选择了id为&c" + clickedBlock.getTypeId() + "&f:&c" + clickedBlock.getData() + "&e的方块");
                    success(player, "输入/bp pick set <名称> <采集时间> <恢复时间> &e来设置该采集物属性");
                }else {
                    success(player, "你选中了采集物 id:&e" + pickBlock.getPickItemId());
                    success(player, "输入/bp pick del &e来删除该采集物");
                }
            }else if(action.equalsIgnoreCase("editPick")){
                event.setCancelled(true);
                //如果玩家编辑采集物

                //1. 判断方块是否为采集物
                PickBlockData pickBlock = PickAPI.isPickBlock(clickedBlock);
                if(pickBlock==null){
                    //如果不是采集物,提示
                    error(player,"你选择的不是一个可采集物品!");
                    return;
                }
                //如果是
                success(player,"你选中了采集物 id:&e"+pickBlock.getPickItemId());
                //判断用户是左键还是右键
                switch (event.getAction()){
                    case LEFT_CLICK_BLOCK:
                        success(player,"你打开了采集工具管理界面");
                        Inventory pickToolsUI = Bukkit.createInventory(null, 54, "§b§l采集工具管理菜单");
                        //把已设置的采集工具添加到ui中
                        for (gd.qaq.blue.bluespick.entity.ItemStack need : pickBlock.getNeeds()) {
                            pickToolsUI.setItem(need.getPosition(),need.getItem());
                        }
                        player.openInventory(pickToolsUI);
                        break;
                    case RIGHT_CLICK_BLOCK:
                        success(player,"你打开了采集掉落物管理界面");
                        Inventory dropToolsUI = Bukkit.createInventory(null, 54, "§e§l掉落物管理菜单");
                        //把已设置的采集工具添加到ui中
                        for (gd.qaq.blue.bluespick.entity.ItemStack drop : pickBlock.getDrops()) {
                            dropToolsUI.setItem(drop.getPosition(),drop.getItem());
                        }
                        player.openInventory(dropToolsUI);
                        break;
                }
                locations[2] = clickedBlock.getLocation();
                choosingPlayers.put(uuid, locations);
            }
        }
    }

    private String checkHand(PlayerInteractEvent event, ItemStack item) {
        if (checkItemHasMeta(item, BluesPick.config.getString("chooseToolID"), colorFormat("&b采集插件选区工具"), colorFormat("&d这是一个选区工具~"), colorFormat("&6作者:blue,qq862899738"), colorFormat("&6插件交流群:&f540900839"), colorFormat("&d&l接插件定制!!"))) {
            if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
                return "left";
            } else if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                return "right";
            }
        } else if (checkItemHasMeta(item, BluesPick.config.getString("pickToolID"), colorFormat("&d采集物设置工具"), colorFormat("&d这是采集物设置工具~"))) {
            if (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                return "setPick";
            }
        } else if(checkItemHasMeta(item,BluesPick.config.getString("editToolID"),  colorFormat("&a采集物编辑工具"), colorFormat("&a这是采集物编辑工具~"),colorFormat("&e左键点击采集物可以编辑采集工具"),colorFormat("&e右键点击采集物可以编辑采集掉落物"))){
            if (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                return "editPick";
            }
        }else{
            //如果玩家右键，判断一下玩家是否在点击采集方块
            if(event.getAction()==Action.RIGHT_CLICK_BLOCK){
                Block clickedBlock = event.getClickedBlock();
                PickBlockData pickBlock = PickAPI.isPickBlock(clickedBlock);
                //如果不是空说明是在采集
                if(pickBlock!=null){
                    return "picking";
                }
            }
        }
        return null;
    }
}
